namespace NFTRedit
{
    using System;
    using System.Collections.Generic;
    using System.IO;

    public class CharacterTable
    {
        private SortedDictionary<char, ushort> charToCode = new SortedDictionary<char, ushort>();
        private SortedDictionary<ushort, char> codeToChar = new SortedDictionary<ushort, char>();

        public bool Exists(char c)
        {
            ushort num;
            return this.charToCode.TryGetValue(c, out num);
        }

        public bool Exists(ushort code)
        {
            char ch;
            return this.codeToChar.TryGetValue(code, out ch);
        }

        public char GetCharByCode(ushort code)
        {
            return this.codeToChar[code];
        }

        public ushort GetCodeByChar(char c)
        {
            return this.charToCode[c];
        }

        public void Load(StreamReader data)
        {
            string str;
            this.codeToChar.Clear();
            this.charToCode.Clear();
            while ((str = data.ReadLine()) != null)
            {
                int index = str.IndexOf('=');
                ushort key = 0;
                if (index != -1)
                {
                    string str2 = str.Substring(0, index);
                    switch (index)
                    {
                        case 2:
                            key = Convert.ToByte(str2, 0x10);
                            break;

                        case 4:
                            key = Convert.ToUInt16(str2, 0x10);
                            break;

                        default:
                            throw new FormatException("Character table contains badly formatted entry " + str);
                    }
                    string str3 = str.Substring(index + 1);
                    if (str3.Length != 1)
                    {
                        throw new FormatException("Character table contains two characters for entry " + str2);
                    }
                    char ch = str3[0];
                    try
                    {
                        this.codeToChar.Add(key, ch);
                    }
                    catch (ArgumentException)
                    {
                        throw new ArgumentException("Duplicate entry found for code " + str2 + ".");
                    }
                    try
                    {
                        this.charToCode.Add(ch, key);
                        continue;
                    }
                    catch (ArgumentException)
                    {
                        throw new ArgumentException("Duplicate entry found for character " + ch + ".");
                    }
                }
            }
        }

        public bool Reassign(ushort code, char c)
        {
            if (this.Exists(c))
            {
                return false;
            }
            this.Remove(code);
            this.codeToChar.Add(code, c);
            this.charToCode.Add(c, code);
            return true;
        }

        public bool Remove(ushort code)
        {
            if (!this.Exists(code))
            {
                return false;
            }
            char key = this.codeToChar[code];
            this.codeToChar.Remove(code);
            this.charToCode.Remove(key);
            return true;
        }

        public void Save(StreamWriter data)
        {
            foreach (KeyValuePair<ushort, char> pair in this.codeToChar)
            {
                if (pair.Key < 0x100)
                {
                    data.WriteLine(string.Format("{0:x2}={1}", pair.Key, pair.Value));
                }
                else
                {
                    data.WriteLine(string.Format("{0:x4}={1}", pair.Key, pair.Value));
                }
            }
        }
    }
}

